package com.bckj.fastboot.iot.biz.core.device.fsm;

import com.alibaba.cola.statemachine.Action;
import com.alibaba.cola.statemachine.builder.StateMachineBuilder;
import com.alibaba.cola.statemachine.builder.StateMachineBuilderFactory;
import com.bckj.fastboot.iot.biz.service.IotDeviceLifecycleService;
import com.bckj.fastboot.iot.common.dto.ctx.IotDeviceContext;
import com.bckj.fastboot.iot.common.enums.IotDeviceEvent;
import com.bckj.fastboot.iot.common.enums.IotDeviceState;
import com.bckj.fastboot.iot.common.enums.IotFsmIdEnum;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * IotDeviceStateMachine
 *
 * @author wfc
 **/
@Slf4j
@Component
@RequiredArgsConstructor
public class IotDeviceStateMachine {

    private final IotDeviceLifecycleService iotDeviceLifecycleService;

    @PostConstruct
    public void init() {
        //初始化状态机
        StateMachineBuilder<IotDeviceState, IotDeviceEvent, IotDeviceContext> builder
                = StateMachineBuilderFactory.create();

        // 1. 设备注册
        builder.externalTransition()
                .from(IotDeviceState.UNREGISTERED)
                .to(IotDeviceState.REGISTERED)
                .on(IotDeviceEvent.REGISTER)
                .perform(doRegisterAction());

        // 2. 注册后连接上线
        builder.externalTransition()
                .from(IotDeviceState.REGISTERED)
                .to(IotDeviceState.ONLINE)
                .on(IotDeviceEvent.CONNECT)
                .perform(doConnectAction());

        // 3. 在线设备断开连接
        builder.externalTransition()
                .from(IotDeviceState.ONLINE)
                .to(IotDeviceState.OFFLINE)
                .on(IotDeviceEvent.DISCONNECT)
                .perform(doDisconnectAction());

        // 4. 断线设备重连上线
        builder.externalTransition()
                .from(IotDeviceState.OFFLINE)
                .to(IotDeviceState.ONLINE)
                .on(IotDeviceEvent.CONNECT)
                .perform(doReconnectAction());

        // 5. 设备上报故障，进入 FAULT
        builder.externalTransition()
                .from(IotDeviceState.ONLINE)
                .to(IotDeviceState.FAULT)
                .on(IotDeviceEvent.REPORT_FAULT)
                .perform(doFaultAction());

        // 6. 故障设备被修复，恢复 ONLINE
        builder.externalTransition()
                .from(IotDeviceState.FAULT)
                .to(IotDeviceState.ONLINE)
                .on(IotDeviceEvent.REPAIR)
                .perform(doRepairAction());

        // 7. 禁用设备（可从多个状态，这里简化为 ONLINE / OFFLINE / FAULT）
        builder.externalTransition()
                .from(IotDeviceState.ONLINE)
                .to(IotDeviceState.DISABLED)
                .on(IotDeviceEvent.DISABLE)
                .perform(doDisableAction());

        builder.externalTransition()
                .from(IotDeviceState.OFFLINE)
                .to(IotDeviceState.DISABLED)
                .on(IotDeviceEvent.DISABLE)
                .perform(doDisableAction());

        builder.externalTransition()
                .from(IotDeviceState.FAULT)
                .to(IotDeviceState.DISABLED)
                .on(IotDeviceEvent.DISABLE)
                .perform(doDisableAction());

        // 8. 启用设备（从 DISABLED 恢复为 ONLINE）
        builder.externalTransition()
                .from(IotDeviceState.DISABLED)
                .to(IotDeviceState.ONLINE)
                .on(IotDeviceEvent.ENABLE)
                .perform(doEnableAction());

        builder.build(IotFsmIdEnum.DEVICE_STATE_MACHINE.getId());
    }

    private Action<IotDeviceState, IotDeviceEvent, IotDeviceContext> doRegisterAction() {
        return (from, to, event, ctx) -> {
            log.info("设备注册：{}", ctx.getDevCode());
        };
    }

    private Action<IotDeviceState, IotDeviceEvent, IotDeviceContext> doConnectAction() {
        return (from, to, event, ctx) -> {
            log.info("设备上线：{}", ctx.getDevCode());
            iotDeviceLifecycleService.onDeviceOnline(ctx);
        };
    }

    private Action<IotDeviceState, IotDeviceEvent, IotDeviceContext> doDisconnectAction() {
        return (from, to, event, ctx) -> {
            log.info("设备下线：{}", ctx.getDevCode());
            iotDeviceLifecycleService.onDeviceOffline(ctx);
        };
    }

    private Action<IotDeviceState, IotDeviceEvent, IotDeviceContext> doReconnectAction() {
        return (from, to, event, ctx) -> {
            log.info("设备重连：{}", ctx.getDevCode());
            iotDeviceLifecycleService.onDeviceOnline(ctx);
        };
    }

    private Action<IotDeviceState, IotDeviceEvent, IotDeviceContext> doFaultAction() {
        return (from, to, event, ctx) -> {
            log.info("设备故障：{}", ctx.getDevCode());
            iotDeviceLifecycleService.onDeviceFault(ctx);
        };
    }

    private Action<IotDeviceState, IotDeviceEvent, IotDeviceContext> doRepairAction() {
        return (from, to, event, ctx) -> {
            log.info("设备修复：{}", ctx.getDevCode());
            iotDeviceLifecycleService.onDeviceRepair(ctx);
        };
    }

    private Action<IotDeviceState, IotDeviceEvent, IotDeviceContext> doDisableAction() {
        return (from, to, event, ctx) -> {
            log.info("设备禁用：{}", ctx.getDevCode());
            iotDeviceLifecycleService.onDeviceDisable(ctx);
        };
    }

    private Action<IotDeviceState, IotDeviceEvent, IotDeviceContext> doEnableAction() {
        return (from, to, event, ctx) -> {
            log.info("设备启用：{}", ctx.getDevCode());
            iotDeviceLifecycleService.onDeviceEnable(ctx);
        };
    }

}
